#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<math.h>
#include<stdlib.h>
//单个二叉树节点的定义
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	int val;

}BTNode;

#include"Queue.h"

//获得二叉树节点 函数
BTNode* BuyNode(int x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	node->left = NULL;
	node->right = NULL;
	node->val = x;

	return node;
}
//前序遍历二叉树 函数
void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;

	}

	printf("%d ", root->val);
	PrevOrder(root->left);
	PrevOrder(root->right);

}
//中序遍历二叉树 函数
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;

	}

	InOrder(root->left);
	printf("%d ", root->val);
	InOrder(root->right);

}
//后序遍历二叉树 函数
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;

	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->val);

}
//求二叉树节点总数 函数
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;

}
//求二叉树叶子节点 函数
int TreeleafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;

	return TreeleafSize(root->left) + TreeleafSize(root->right);

}
//求二叉树第K层节点数 函数
int TreeKLevel(BTNode* root, int k)
{
	assert(k > 0);
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;

	return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}
//求二叉树的高度 函数
int TreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;


	return fmax(TreeHeight(root->left), TreeHeight(root->right)) + 1;

}

//在二叉树中查找值为x的节点 函数
BTNode* TreeFind(BTNode* root, int x)
{
	if (root == NULL)
		return NULL;
	if (root->val == x)
		return root;

	BTNode* ret = NULL;
	ret = TreeFind(root->left, x);
	if (ret)
		return ret;

	ret = TreeFind(root->right, x);
	if (ret)
		return ret;

	return NULL;

}

//销毁二叉树 函数
void TreeDestroy(BTNode* root)
{
	if (root == NULL)
		return;

	TreeDestroy(root->left);
	TreeDestroy(root->right);

	free(root);


}
//队列实现二叉树的层序遍历 函数
void LevelOrder(BTNode* root)
{
	Que q;
	QueueInit(&q);

	if (root)
		QueuePush(&q, root);

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		printf("%d ", front->val);

		if (front->left)
			QueuePush(&q, front->left);

		if (front->right)
			QueuePush(&q, front->right);

		QueuePop(&q);

	}
	printf("\n");

	QueueDestroy(&q);

}
//队列验证是否为完全二叉树 函数
int TreeComplete(BTNode* root)
{
	//创建一个队列
	Que q;
	//初始化队列
	QueueInit(&q);

	//不是空节点就入队列
	if (root)
		QueuePush(&q, root);

	//队列不为空就进循环
	while (!QueueEmpty(&q))
	{
		//获取对头
		BTNode* front = QueueFront(&q);
		//对对头判断是否为空
		if (front == NULL)
			//为空即跳出while，对队列后面剩余的进行检测
			break;
		//对头不为空，即将此对头的两个孩子入队列
		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
		//对头出队列
		QueuePop(&q);
	}
	//对NULL后的队列中的剩余节点，进行检测
	while (!QueueEmpty(&q))
	{
		//获取对头
		BTNode* front = QueueFront(&q);
		//对头出队列
		QueuePop(&q);
		//对对头进行检测
		//为非空，即不是完全二叉树
		if (front != NULL)
		{
			//摧毁二叉树
			QueueDestroy(&q);
			//返回false
			return false;
		}
	}
	//来到这里，代表检测通过了
	//销毁二叉树
	QueueDestroy(&q);
	//返回true
	return true;
}

//主函数
int main()
{
	//获取模型中的节点
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);


	//模拟模型中的指向
	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;



	//验证前序遍历 函数
	PrevOrder(node1);
	printf("\n");
	//验证中序遍历 函数
	InOrder(node1);
	printf("\n");
	//验证后序遍历 函数
	PostOrder(node1);
	printf("\n");

	//验证TreeSize(求节点总数)函数
	printf("节点总数 = %d", TreeSize(node1));
	printf("\n");
	//验证TreeleafSize(求叶子节点总数)函数
	printf("叶子节点总数 = %d", TreeleafSize(node1));
	printf("\n");
	//验证TreeleafSize(求叶子节点总数)函数
	printf("叶子节点总数 =%d", TreeleafSize(node4));
	printf("\n");
	//验证TreeKLevel(求第K层节点总数)函数
	printf("第k层的节点数 = %d", TreeKLevel(node1, 3));
	printf("\n");

	//验证TreeHeight(求二叉树高度)函数
	printf("高度 = %d", TreeHeight(node1));
	printf("\n");

	//验证LevelOrder(用队列实现二叉树层序遍历)函数
	LevelOrder(node1);
	printf("\n");
	//验证TreeComplete(用队列验证是否为完全二叉树)
	printf("TreeComplete：%d\n", TreeComplete(node1));
	printf("\n");


	return 0;
}
